#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
文件统计导出器
支持导出所有文件的详细统计数据为 Excel 和 CSV 格式
"""

import csv
from typing import Dict
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
from openpyxl.utils import get_column_letter
import datetime


class FileStatsExporter:
    """文件统计数据导出器"""
    
    def __init__(self, repo_path: str, user_name: str, user_email: str, branch: str):
        """
        初始化导出器
        
        Args:
            repo_path: 仓库路径
            user_name: Git 用户名
            user_email: Git 邮箱
            branch: 分支名
        """
        self.repo_path = repo_path
        self.user_name = user_name
        self.user_email = user_email
        self.branch = branch
        self.timestamp = datetime.datetime.now()
    
    def export_to_excel(self, file_stats: Dict, stats: Dict, output_path: str = None, per_user_stats: Dict = None, user_list: list = None) -> str:
        """
        导出为 Excel 文件
        
        Args:
            file_stats: 文件统计数据
            stats: 总体统计数据
            output_path: 输出路径（可选）
            per_user_stats: 分账户统计数据（可选）
            user_list: 用户列表（可选）
        
        Returns:
            保存的文件路径
        """
        if output_path is None:
            output_path = f"file_stats_{self.timestamp.strftime('%Y%m%d_%H%M%S')}.xlsx"
        
        # 创建工作簿
        wb = Workbook()
        
        # 创建汇总概要表
        self._create_summary_sheet(wb, stats, is_detailed=per_user_stats is not None)
        
        # 如果有分账户数据，创建分账户工作表
        if per_user_stats and user_list:
            # 为每个账户创建工作表
            for user in user_list:
                if user in per_user_stats:
                    user_data = per_user_stats[user]
                    self._create_user_sheet(wb, user, user_data['stats'], user_data['file_stats'])
            
            # 创建对比表
            self._create_comparison_sheet(wb, per_user_stats, user_list, stats)
        
        # 创建详细文件列表
        self._create_files_sheet(wb, file_stats)
        
        # 创建分类统计表
        self._create_category_sheet(wb, file_stats)
        
        # 保存文件
        wb.save(output_path)
        
        return output_path
    
    def _create_summary_sheet(self, wb: Workbook, stats: Dict, is_detailed: bool = False):
        """创建概要表"""
        ws = wb.active
        ws.title = "汇总统计" if is_detailed else "统计概要"
        
        # 设置样式
        header_fill = PatternFill(start_color="4472C4", end_color="4472C4", fill_type="solid")
        header_font = Font(color="FFFFFF", bold=True, size=12)
        title_font = Font(bold=True, size=14)
        border = Border(
            left=Side(style='thin'),
            right=Side(style='thin'),
            top=Side(style='thin'),
            bottom=Side(style='thin')
        )
        
        # 标题
        ws['A1'] = "Git 代码统计报告"
        ws['A1'].font = Font(bold=True, size=16, color="4472C4")
        ws.merge_cells('A1:D1')
        
        # 统计说明
        row = 2
        ws[f'A{row}'] = "📊 统计说明"
        ws[f'A{row}'].font = Font(bold=True, size=11, color="FF8C00")
        ws.merge_cells(f'A{row}:D{row}')
        
        row += 1
        ws[f'A{row}'] = "本报告仅统计下方指定用户的 Git 提交记录，基于 Git diff 分析。"
        ws[f'A{row}'].font = Font(size=10, color="666666")
        ws.merge_cells(f'A{row}:D{row}')
        
        row += 1
        ws[f'A{row}'] = "不包括项目原始代码，只统计该用户新增/删除的代码（已排除注释和空行）。"
        ws[f'A{row}'].font = Font(size=10, color="666666")
        ws.merge_cells(f'A{row}:D{row}')
        
        # 基本信息
        row += 2
        info_data = [
            ("统计用户（开发者）", self.user_name),
            ("用户邮箱", self.user_email),
            ("仓库路径", self.repo_path),
            ("分支", self.branch),
            ("生成时间", self.timestamp.strftime('%Y-%m-%d %H:%M:%S'))
        ]
        
        for label, value in info_data:
            ws[f'A{row}'] = label
            ws[f'A{row}'].font = Font(bold=True)
            ws[f'B{row}'] = value
            ws.merge_cells(f'B{row}:D{row}')
            row += 1
        
        # 统计数据
        row += 1
        ws[f'A{row}'] = "统计数据"
        ws[f'A{row}'].font = title_font
        ws.merge_cells(f'A{row}:D{row}')
        
        row += 1
        # 检查是否有当前代码量数据
        has_current = any('current' in stats[key] and stats[key]['current'] > 0 for key in stats)
        
        if has_current:
            headers = ['类型', '新增行数', '删除行数', '净增行数', '当前拥有']
        else:
            headers = ['类型', '新增行数', '删除行数', '净增行数']
        for col, header in enumerate(headers, 1):
            cell = ws.cell(row=row, column=col)
            cell.value = header
            cell.font = header_font
            cell.fill = header_fill
            cell.alignment = Alignment(horizontal='center', vertical='center')
            cell.border = border
        
        # 数据行
        if has_current:
            data_rows = [
                ('前端代码', stats['frontend']['added'], stats['frontend']['deleted'], 
                 stats['frontend']['total'], stats['frontend'].get('current', 0)),
                ('后端代码', stats['backend']['added'], stats['backend']['deleted'], 
                 stats['backend']['total'], stats['backend'].get('current', 0)),
                ('其他文件', stats['other']['added'], stats['other']['deleted'], 
                 stats['other']['total'], stats['other'].get('current', 0)),
            ]
        else:
            data_rows = [
                ('前端代码', stats['frontend']['added'], stats['frontend']['deleted'], stats['frontend']['total']),
                ('后端代码', stats['backend']['added'], stats['backend']['deleted'], stats['backend']['total']),
                ('其他文件', stats['other']['added'], stats['other']['deleted'], stats['other']['total']),
            ]
        
        total_added = stats['frontend']['added'] + stats['backend']['added'] + stats['other']['added']
        total_deleted = stats['frontend']['deleted'] + stats['backend']['deleted'] + stats['other']['deleted']
        total_net = stats['frontend']['total'] + stats['backend']['total'] + stats['other']['total']
        total_current = stats['frontend'].get('current', 0) + stats['backend'].get('current', 0) + stats['other'].get('current', 0)
        
        row += 1
        for data_row in data_rows:
            for col, value in enumerate(data_row, 1):
                cell = ws.cell(row=row, column=col)
                cell.value = value
                cell.border = border
                if col > 1:
                    cell.alignment = Alignment(horizontal='right')
                    cell.number_format = '#,##0'
            row += 1
        
        # 总计行
        if has_current:
            total_row_data = ('总计', total_added, total_deleted, total_net, total_current)
        else:
            total_row_data = ('总计', total_added, total_deleted, total_net)
        for col, value in enumerate(total_row_data, 1):
            cell = ws.cell(row=row, column=col)
            cell.value = value
            cell.font = Font(bold=True)
            cell.fill = PatternFill(start_color="E7E6E6", end_color="E7E6E6", fill_type="solid")
            cell.border = border
            if col > 1:
                cell.alignment = Alignment(horizontal='right')
                cell.number_format = '#,##0'
        
        # 调整列宽
        ws.column_dimensions['A'].width = 15
        ws.column_dimensions['B'].width = 50
        ws.column_dimensions['C'].width = 15
        ws.column_dimensions['D'].width = 15
    
    def _create_files_sheet(self, wb: Workbook, file_stats: Dict):
        """创建详细文件列表"""
        ws = wb.create_sheet("所有文件明细")
        
        # 样式
        header_fill = PatternFill(start_color="70AD47", end_color="70AD47", fill_type="solid")
        header_font = Font(color="FFFFFF", bold=True, size=11)
        border = Border(
            left=Side(style='thin'),
            right=Side(style='thin'),
            top=Side(style='thin'),
            bottom=Side(style='thin')
        )
        
        # 检查是否有当前代码量数据
        has_current = any('current' in stats and stats['current'] > 0 for stats in file_stats.values())
        
        # 表头
        if has_current:
            headers = ['排名', '文件路径', '新增行数', '删除行数', '净增行数', '当前拥有', '变更总数']
        else:
            headers = ['排名', '文件路径', '新增行数', '删除行数', '净增行数', '变更总数']
        for col, header in enumerate(headers, 1):
            cell = ws.cell(row=1, column=col)
            cell.value = header
            cell.font = header_font
            cell.fill = header_fill
            cell.alignment = Alignment(horizontal='center', vertical='center')
            cell.border = border
        
        # 排序文件（按净增行数），过滤掉没有贡献的文件
        sorted_files = sorted(
            [(f, s) for f, s in file_stats.items() if s['added'] > 0 or s['deleted'] > 0],
            key=lambda x: x[1]['added'] - x[1]['deleted'],
            reverse=True
        )
        
        # 数据行
        for idx, (file_path, stats) in enumerate(sorted_files, 1):
            row = idx + 1
            net_change = stats['added'] - stats['deleted']
            total_change = stats['added'] + stats['deleted']
            current_lines = stats.get('current', 0)
            
            if has_current:
                data = [idx, file_path, stats['added'], stats['deleted'], net_change, current_lines, total_change]
            else:
                data = [idx, file_path, stats['added'], stats['deleted'], net_change, total_change]
            
            for col, value in enumerate(data, 1):
                cell = ws.cell(row=row, column=col)
                cell.value = value
                cell.border = border
                
                if col == 1:  # 排名
                    cell.alignment = Alignment(horizontal='center')
                    if idx <= 3:
                        cell.font = Font(bold=True, color="C00000")
                elif col > 2:  # 数字列
                    cell.alignment = Alignment(horizontal='right')
                    cell.number_format = '#,##0'
                    
                    # 净增行数颜色标记
                    net_col = 6 if has_current else 5
                    if col == net_col:
                        if net_change > 0:
                            cell.font = Font(color="008000")  # 绿色
                        elif net_change < 0:
                            cell.font = Font(color="C00000")  # 红色
        
        # 调整列宽
        ws.column_dimensions['A'].width = 8
        ws.column_dimensions['B'].width = 60
        ws.column_dimensions['C'].width = 12
        ws.column_dimensions['D'].width = 12
        ws.column_dimensions['E'].width = 12
        ws.column_dimensions['F'].width = 12
        if has_current:
            ws.column_dimensions['G'].width = 12
        
        # 冻结首行
        ws.freeze_panes = 'A2'
    
    def _create_category_sheet(self, wb: Workbook, file_stats: Dict):
        """创建按类型分类的统计表"""
        ws = wb.create_sheet("分类统计")
        
        # 样式
        header_fill = PatternFill(start_color="FFC000", end_color="FFC000", fill_type="solid")
        header_font = Font(color="FFFFFF", bold=True, size=11)
        border = Border(
            left=Side(style='thin'),
            right=Side(style='thin'),
            top=Side(style='thin'),
            bottom=Side(style='thin')
        )
        
        # 按文件扩展名分类
        extension_stats = {}
        for file_path, stats in file_stats.items():
            import os
            _, ext = os.path.splitext(file_path.lower())
            ext = ext if ext else '(无扩展名)'
            
            if ext not in extension_stats:
                extension_stats[ext] = {
                    'count': 0,
                    'added': 0,
                    'deleted': 0
                }
            
            extension_stats[ext]['count'] += 1
            extension_stats[ext]['added'] += stats['added']
            extension_stats[ext]['deleted'] += stats['deleted']
        
        # 表头
        headers = ['文件类型', '文件数量', '新增行数', '删除行数', '净增行数']
        for col, header in enumerate(headers, 1):
            cell = ws.cell(row=1, column=col)
            cell.value = header
            cell.font = header_font
            cell.fill = header_fill
            cell.alignment = Alignment(horizontal='center', vertical='center')
            cell.border = border
        
        # 排序（按文件数量）
        sorted_extensions = sorted(
            extension_stats.items(),
            key=lambda x: x[1]['count'],
            reverse=True
        )
        
        # 数据行
        for idx, (ext, stats) in enumerate(sorted_extensions, 1):
            row = idx + 1
            net_change = stats['added'] - stats['deleted']
            
            data = [ext, stats['count'], stats['added'], stats['deleted'], net_change]
            
            for col, value in enumerate(data, 1):
                cell = ws.cell(row=row, column=col)
                cell.value = value
                cell.border = border
                
                if col > 1:  # 数字列
                    cell.alignment = Alignment(horizontal='right')
                    cell.number_format = '#,##0'
                    
                    if col == 5 and net_change > 0:
                        cell.font = Font(color="008000")
                    elif col == 5 and net_change < 0:
                        cell.font = Font(color="C00000")
        
        # 调整列宽
        ws.column_dimensions['A'].width = 15
        ws.column_dimensions['B'].width = 12
        ws.column_dimensions['C'].width = 12
        ws.column_dimensions['D'].width = 12
        ws.column_dimensions['E'].width = 12
        
        # 冻结首行
        ws.freeze_panes = 'A2'
    
    def export_to_csv(self, file_stats: Dict, output_path: str = None) -> str:
        """
        导出为 CSV 文件
        
        Args:
            file_stats: 文件统计数据
            output_path: 输出路径（可选）
        
        Returns:
            保存的文件路径
        """
        if output_path is None:
            output_path = f"file_stats_{self.timestamp.strftime('%Y%m%d_%H%M%S')}.csv"
        
        # 排序文件
        sorted_files = sorted(
            file_stats.items(),
            key=lambda x: x[1]['added'] - x[1]['deleted'],
            reverse=True
        )
        
        # 写入 CSV
        with open(output_path, 'w', encoding='utf-8-sig', newline='') as f:
            writer = csv.writer(f)
            
            # 基本信息
            writer.writerow(['Git 代码统计报告'])
            writer.writerow([])
            writer.writerow(['📊 统计说明'])
            writer.writerow(['本报告仅统计下方指定用户的 Git 提交记录，基于 Git diff 分析。'])
            writer.writerow(['不包括项目原始代码，只统计该用户新增/删除的代码（已排除注释和空行）。'])
            writer.writerow([])
            writer.writerow(['统计用户（开发者）', self.user_name])
            writer.writerow(['用户邮箱', self.user_email])
            writer.writerow(['仓库路径', self.repo_path])
            writer.writerow(['分支', self.branch])
            writer.writerow(['生成时间', self.timestamp.strftime('%Y-%m-%d %H:%M:%S')])
            writer.writerow([])
            
            # 检查是否有当前代码量数据
            has_current = any('current' in stats and stats['current'] > 0 for stats in file_stats.values())
            
            # 表头
            if has_current:
                writer.writerow(['排名', '文件路径', '新增行数', '删除行数', '净增行数', '当前拥有', '变更总数'])
            else:
                writer.writerow(['排名', '文件路径', '新增行数', '删除行数', '净增行数', '变更总数'])
            
            # 数据
            for idx, (file_path, stats) in enumerate(sorted_files, 1):
                net_change = stats['added'] - stats['deleted']
                total_change = stats['added'] + stats['deleted']
                current_lines = stats.get('current', 0)
                
                if has_current:
                    writer.writerow([
                        idx,
                        file_path,
                        stats['added'],
                        stats['deleted'],
                        net_change,
                        current_lines,
                        total_change
                    ])
                else:
                    writer.writerow([
                        idx,
                        file_path,
                        stats['added'],
                        stats['deleted'],
                        net_change,
                        total_change
                    ])
        
        return output_path
    
    def _create_user_sheet(self, wb: Workbook, user: str, user_stats: Dict, user_file_stats: Dict):
        """为单个账户创建工作表"""
        # 创建新工作表，处理特殊字符
        safe_user = user.replace('<', '').replace('>', '').replace(':', '').replace('/', '')[:31]
        ws = wb.create_sheet(title=safe_user)
        
        # 样式
        header_fill = PatternFill(start_color="4472C4", end_color="4472C4", fill_type="solid")
        header_font = Font(color="FFFFFF", bold=True)
        
        # 标题
        ws['A1'] = f"账户：{user}"
        ws['A1'].font = Font(bold=True, size=14, color="4472C4")
        ws.merge_cells('A1:D1')
        
        row = 3
        
        # 统计数据
        ws[f'A{row}'] = "分类"
        ws[f'B{row}'] = "累计新增"
        ws[f'C{row}'] = "累计删除"
        ws[f'D{row}'] = "净增"
        ws[f'E{row}'] = "当前拥有"
        
        for col in ['A', 'B', 'C', 'D', 'E']:
            ws[f'{col}{row}'].fill = header_fill
            ws[f'{col}{row}'].font = header_font
        
        row += 1
        for category, label in [('frontend', '前端'), ('backend', '后端'), ('other', '其他')]:
            ws[f'A{row}'] = label
            ws[f'B{row}'] = user_stats[category]['added']
            ws[f'C{row}'] = user_stats[category]['deleted']
            ws[f'D{row}'] = user_stats[category]['total']
            ws[f'E{row}'] = user_stats[category]['current']
            ws[f'B{row}'].number_format = '#,##0'
            ws[f'C{row}'].number_format = '#,##0'
            ws[f'D{row}'].number_format = '#,##0'
            ws[f'E{row}'].number_format = '#,##0'
            row += 1
        
        # 文件明细
        row += 2
        ws[f'A{row}'] = "文件列表"
        ws[f'A{row}'].font = Font(bold=True, size=12)
        ws.merge_cells(f'A{row}:E{row}')
        
        row += 1
        ws[f'A{row}'] = "文件路径"
        ws[f'B{row}'] = "新增"
        ws[f'C{row}'] = "删除"
        ws[f'D{row}'] = "净增"
        ws[f'E{row}'] = "当前拥有"
        
        for col in ['A', 'B', 'C', 'D', 'E']:
            ws[f'{col}{row}'].fill = header_fill
            ws[f'{col}{row}'].font = header_font
        
        row += 1
        # 过滤掉没有贡献的文件
        filtered_files = [(f, s) for f, s in user_file_stats.items() if s['added'] > 0 or s['deleted'] > 0 or s.get('current', 0) > 0]
        for file_path, stats in sorted(filtered_files, key=lambda x: x[1]['added'], reverse=True):
            ws[f'A{row}'] = file_path
            ws[f'B{row}'] = stats['added']
            ws[f'C{row}'] = stats['deleted']
            ws[f'D{row}'] = stats['added'] - stats['deleted']
            ws[f'E{row}'] = stats.get('current', 0)
            ws[f'B{row}'].number_format = '#,##0'
            ws[f'C{row}'].number_format = '#,##0'
            ws[f'D{row}'].number_format = '#,##0'
            ws[f'E{row}'].number_format = '#,##0'
            row += 1
        
        # 调整列宽
        ws.column_dimensions['A'].width = 50
        for col in ['B', 'C', 'D', 'E']:
            ws.column_dimensions[col].width = 15
    
    def _create_comparison_sheet(self, wb: Workbook, per_user_stats: Dict, user_list: list, total_stats: Dict):
        """创建对比表"""
        ws = wb.create_sheet(title="账户对比")
        
        # 样式
        header_fill = PatternFill(start_color="FF6B6B", end_color="FF6B6B", fill_type="solid")
        header_font = Font(color="FFFFFF", bold=True)
        title_font = Font(bold=True, size=14, color="FF6B6B")
        
        # 标题
        ws['A1'] = "账户对比分析"
        ws['A1'].font = title_font
        ws.merge_cells('A1:K1')
        
        row = 3
        
        # 表头
        headers = ['账户', '前端新增', '前端删除', '前端当前', '后端新增', '后端删除', '后端当前', '总新增', '总删除', '总当前', '贡献占比']
        for col_idx, header in enumerate(headers, 1):
            cell = ws.cell(row=row, column=col_idx)
            cell.value = header
            cell.fill = header_fill
            cell.font = header_font
            cell.alignment = Alignment(horizontal='center')
        
        # 数据
        total_current = sum(per_user_stats[user]['stats']['frontend']['current'] + 
                           per_user_stats[user]['stats']['backend']['current'] + 
                           per_user_stats[user]['stats']['other']['current']
                           for user in user_list if user in per_user_stats)
        
        row += 1
        for user in user_list:
            if user not in per_user_stats:
                continue
            
            stats = per_user_stats[user]['stats']
            
            user_total_current = (stats['frontend']['current'] + 
                                 stats['backend']['current'] + 
                                 stats['other']['current'])
            percentage = (user_total_current / total_current * 100) if total_current > 0 else 0
            
            data = [
                user,
                stats['frontend']['added'],
                stats['frontend']['deleted'],
                stats['frontend']['current'],
                stats['backend']['added'],
                stats['backend']['deleted'],
                stats['backend']['current'],
                stats['frontend']['added'] + stats['backend']['added'] + stats['other']['added'],
                stats['frontend']['deleted'] + stats['backend']['deleted'] + stats['other']['deleted'],
                user_total_current,
                f"{percentage:.1f}%"
            ]
            
            for col_idx, value in enumerate(data, 1):
                cell = ws.cell(row=row, column=col_idx)
                cell.value = value
                if col_idx > 1 and col_idx < 11:
                    cell.number_format = '#,##0'
                cell.alignment = Alignment(horizontal='center' if col_idx > 1 else 'left')
            
            row += 1
        
        # 汇总行
        cell = ws.cell(row=row, column=1)
        cell.value = "总计"
        cell.font = Font(bold=True)
        
        for col_idx in range(2, 11):
            cell = ws.cell(row=row, column=col_idx)
            if col_idx == 2:
                cell.value = total_stats['frontend']['added']
            elif col_idx == 3:
                cell.value = total_stats['frontend']['deleted']
            elif col_idx == 4:
                cell.value = total_stats['frontend']['current']
            elif col_idx == 5:
                cell.value = total_stats['backend']['added']
            elif col_idx == 6:
                cell.value = total_stats['backend']['deleted']
            elif col_idx == 7:
                cell.value = total_stats['backend']['current']
            elif col_idx == 8:
                cell.value = (total_stats['frontend']['added'] + 
                             total_stats['backend']['added'] + 
                             total_stats['other']['added'])
            elif col_idx == 9:
                cell.value = (total_stats['frontend']['deleted'] + 
                             total_stats['backend']['deleted'] + 
                             total_stats['other']['deleted'])
            elif col_idx == 10:
                cell.value = total_current
            
            cell.number_format = '#,##0'
            cell.font = Font(bold=True)
            cell.alignment = Alignment(horizontal='center')
        
        ws.cell(row=row, column=11).value = "100%"
        ws.cell(row=row, column=11).font = Font(bold=True)
        ws.cell(row=row, column=11).alignment = Alignment(horizontal='center')
        
        # 调整列宽
        ws.column_dimensions['A'].width = 30
        for col in ['B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K']:
            ws.column_dimensions[col].width = 12

